home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / util / rexx / cdmp.lha / cdmp.rx < prev   
Text File  |  2000-11-26  |  29KB  |  973 lines

  1. /**********************************************************************************************************************
  2.  
  3. $VER: cdmp.rx v1.2 (18.11.2000)
  4.  
  5. Erstellt: J.Klingele 03.2000
  6. Email:    jklingele@gmx.de
  7.  
  8. liest tracks (titel) von cd und wandelt diese ins mp3 format
  9.  
  10. benötigt cdda zum einlesen der CD
  11.      und lame zum erzeugen der mp3 files
  12. Beide im Suchpfad (vorzugsweise c:)
  13.  
  14. V1.0 10.08.2000 - 1. vollständige, inoffizielle Version - jk
  15. V1.1 26.08.2000 - Unterstützung von CDID's, bessere Fehlerbehandlung und Kontrolle, Parameter für mp3-extension
  16.                   1. Aminet Release  - jk
  17. V1.2 25.11.2000 - Unterstützung von Pegase, Stackanpassung für PPC-Lame, Default-Name für Worksheets, eigenes Window
  18.                   für CD-Inhalt (Option), kleinere Bugfixes, 2.Aminet Release  - jk
  19.  
  20. ***********************************************************************************************************************/
  21.  
  22.  
  23. /******* Globale Parameter Variablen *******/
  24.  
  25. titelpfad    = "CD-A:"               /* Pfad zum speichern der tracks und sonstiger datenfiles, MUSS mit : oder / enden  */
  26. mp3pfad      = "MP3:"                /* Pfad zum speichern der mp3-files, MUSS mit : oder / enden                        */
  27. cdid_dir     = "CDID:"               /* Pfad zu den CDID's                                                               */
  28.  
  29. titellist    = "titelliste"          /* Dateiname zum abspeichern der eingegeben Titel, wird für Restore benutzt         */
  30. cdlist       = "ram:cdliste"         /* Dateiname der Titelliste von cdda, wird nut temporär zum einlesen verw.          */
  31. mp_ext       = ".mp3"                /* extension für mp3-Dateien                                                        */
  32. cdsave       = "CDsave"              /* Default Name der für spätere Bearbeitung abgespeicherten Listen bei CD ohne ID   */
  33.  
  34. plan         = "e"                   /* cdda-Modus e=atapi                                                               */
  35.  
  36. list_win     = 0                     /* CD-Inhaltsverzeichnis in einem eigenen Fenster anzeigen? 0=nein 1=ja             */
  37. lw_xs        = 150                   /* linke obere Ecke des CD-Inhaltsverzeichnis Fensters Horizontale (x) Position     */
  38. lw_ys        = 10                    /* linke obere Ecke des CD-Inhaltsverzeichnis Fensters Vertikale (y) Position       */
  39. lw_fw        = 9                     /* Breite des verwendeten Shell Fonts +1 (topaz 8=9, 11=9)                          */
  40. lw_fh        = 12                    /* Höhe des verwendeten Shell Fonts +1 (topaz 8=9, 11=12)                           */
  41.  
  42. encoder      = "lame"                /* gewünschter encoder, "lame" oder "pegase" (lowercase!!)                            */
  43. lameopt      = "-b 160"              /* optionstring für lame                                                            */
  44. pegaseopt    = "LAYER 2 BITRATE 160" /* optionstring for pegase                                                          */
  45. lame_ppc     = 1                     /* PPC-Version von Lame im Einsatz? 0=nein 1=ja                                     */
  46. ppc_stack    = 200000                /* Stackwert für PPC-Lame                                                           */
  47.  
  48. debug        = 0                     /* Debugmode und -anzeige? 0=nein 1=ja                                              */
  49. del_titel    = 1                     /* CD-Titel nach Konvertierung löschen? 0=nein 1=ja                                 */
  50. bpb          = 2352                  /* Bytes per Block ca. Wert                                                         */
  51. skip_lo      = 150                   /* Anzahl der Blocks die vom Leadout abgezogen werden. 1s ca. 75 Blocks (2s)        */
  52. repl_spc     = 1                     /* Bei Eingabe der CD-Titelnamen Leerzeichen durch '_' ersetzen 0=nein 1=ja         */
  53.  
  54. max_name_len = 30                    /* max. Dateinamenlänge ffs=30 Zeichen                                              */
  55. dirty_char   = '~%#?<>|()[]":`;*'    /* ungültige Zeichen die bei der Namenseingabe ersetzt werden müssen.               */
  56.  
  57.  
  58. /*******************************************
  59.  
  60. Sonstige Globale Variablen
  61.  
  62. {  cd.                       - Stammvariable mit den Daten der einzelnen Titel auf CD
  63.    cd.titel.                 - Daten eines titels
  64.    cd.titel.nr               - Titelnummer
  65.            .name             - Titelname
  66.            .ip               - Interpret
  67.            .cdn              - Dateiname (ohne Pfad) zum abspeichern auf HD
  68.            .start            - Startblock
  69.            .ende             - Endblock
  70.            .laenge           - Laenge in Blocks
  71.            .zeit             - Spielzeit
  72. }
  73.  
  74. {  rip.                      - Stammvariable mit Daten der abzuspeichernden und umzuwandelnden Titel
  75.    rip.titel.                - Daten eines titels
  76.    rip.titel.cdt             - (CD) Titelnummer (dient als Verweis auf cd.titel.nr)
  77.             .mpn             - mp3 Dateiname zum abspeichern
  78.             .cut_lo          - zusätzlicher Abzug vom lead-out (optional per eingabe)
  79. }
  80.  
  81. anz_titel                    - Anzahl der Titel auf CD
  82. anz_save                     - Anzahl der Titel die eingelesen werden sollen
  83. mp3                          - mit mp3 Konvertierung j/n
  84. restore                      - restorefunktion, alte Daten verwenden j/n
  85. listname                     - übergebener dateiname bei Programmaufruf, sollte bestehende Titelliste enthalten
  86. list_in                      - dateiname zum einlesen einer titelliste (wird entw. auf titellist oder listname gesetzt)
  87. cdid                         - ID String der CD im Laufwerk
  88. cdid_rest                    - ID String der zu bearbeitenden CD bei restore
  89.  
  90.  
  91. Lokale Variablen
  92.  
  93.  a, b, c, akt_t, datei_in, datei_out, cdnr, zeile, gr, cut, temp, dummy
  94.  
  95. 'Lokale' Variablen in Unterprogrammen
  96.  
  97.  sdatei, sstart, sende, sa, s_name, s_len
  98.  
  99. *********************************************/
  100.  
  101. SIGNAL ON break_c  /* abbruch bei CTRL-C */
  102. SIGNAL ON failure  /* abbruch bei Host-Fehler */
  103.  
  104. OPTIONS FAILAT 10
  105.  
  106. anz_titel = -1
  107. anz_save  = -1
  108. mp3       = "N"
  109.  
  110. IF EXISTS(cdid_dir) THEN
  111.   cdid_mode = 1
  112. ELSE
  113.   cdid_mode = 0
  114.  
  115. /** 1. Programmstart mit restore einer gespeicherten Sitzung ? **/
  116.  
  117. /* Dateiname zu bestehender Titelliste übergeben ? */
  118. PARSE ARG listname
  119.  
  120. IF listname ~== "" THEN
  121.   list_in = titelpfad||listname
  122.  
  123. ELSE
  124.   list_in = titelpfad||titellist /* ohne Übergabeparameter wird der Standardname fürs Backup verwendet */
  125.  
  126. IF debug == 1 THEN SAY "<"listname">"
  127.  
  128. /** 1a. Prüfen ob Bearbeitung zuvor unterbrochen wurde **/
  129.  
  130. IF EXISTS(list_in) THEN DO
  131.  
  132.   /* alte Werte wieder einlesen */
  133.   OPEN(datei_in,list_in,R)
  134.  
  135.   a = 0
  136.   rip. = ""
  137.  
  138.   cdid_rest = READLN(datei_in)
  139.   mp3       = READLN(datei_in)
  140.  
  141.   DO WHILE ~eof(datei_in)
  142.  
  143.     a = a +1
  144.  
  145.     rip.a.cdt    = READLN(datei_in)
  146.     rip.a.mpn    = READLN(datei_in)
  147.     rip.a.cut_lo = READLN(datei_in)
  148.  
  149.     IF debug == 1 THEN
  150.       SAY "ID: "cdid_rest" - MP3: "mp3" - Titel "a": "rip.a.cdt" - Dateiname : "rip.a.mpn" Abzug : "rip.a.cut_lo
  151.  
  152.   END /* do while */
  153.  
  154.   CLOSE(datei_in)
  155.  
  156.   a = a -1 /* Da das Dateiende hinter der letzen Zeile ist gibts immer einen leeren Satz */
  157.  
  158.   /* Daten vorhanden ?? (>>>>>> evt. mal durch irgendeine Checksumme ersetzen) */
  159.   IF (rip.a.cdt ~== "") & (RIGHT(rip.a.mpn,4) == mp_ext) THEN DO
  160.  
  161.     /* Variablen für nachfolgende Routinen setzen */
  162.     anz_save = a
  163.  
  164.     SAY
  165.     IF mp3 == "J" THEN DO
  166.  
  167.       SAY "> Alte Angaben eingelesen, folgende MP3-files sollen erzeugt werden:"
  168.       SAY
  169.       SAY " CD-Titel | MP3-Name                       | kürzen um"
  170.       SAY "-------------------------------------------------------"
  171.  
  172.       DO a = 1 to anz_save
  173.  
  174.         SAY INSERT('','',0,6-(rip.a.cdt > 9),' ')||rip.a.cdt"   - "rip.a.mpn||INSERT(' ','',1,max_name_len - LENGTH(rip.a.mpn),' ')"- " (skip_lo + rip.a.cut_lo) % 75"s."
  175.  
  176.       END /* Do */
  177.  
  178.     END /* if mp3 */
  179.  
  180.     ELSE DO 
  181.  
  182.       SAY "> Alte Angaben eingelesen, folgende CD-files sollen erzeugt werden:"
  183.       SAY
  184.       SAY " CD-Titel"
  185.       SAY "----------"
  186.  
  187.       DO a = 1 to anz_save
  188.  
  189.         SAY INSERT('','',0,5-(rip.a.cdt > 9))||rip.a.cdt
  190.  
  191.       END /* Do */
  192.  
  193.     END /* else - if mp3 */
  194.  
  195.     SAY
  196.  
  197.     /* Wenn ja, ermitteln ob die alte Sitzung fortgesetzt werden soll */
  198.  
  199.     IF list_in == titelpfad||titellist THEN DO
  200.       SAY "> Soll die abgebrochene Bearbeitung der letzten CD"
  201.       WRITECH(stdout,"> mit diesen Daten weitergeführt werden (j/N)? ")
  202.     END
  203.  
  204.     ELSE DO
  205.       SAY "> Soll die Bearbeitung mit diesen Daten von <"listname">"
  206.       WRITECH(stdout,"> begonnen werden (j/N)? ")
  207.     END
  208.  
  209.     PULL restore
  210.  
  211.     IF restore == "J" THEN DO
  212.  
  213.        /* CD-Liste wird auf alle Fälle wieder neu eingelesen, sicher ist sicher */
  214.        CALL get_toc()
  215.  
  216.        DO WHILE cdid ~== cdid_rest /* warten bis richtige CD eingelegt wurde */
  217.  
  218.           SAY
  219.           SAY "> ACHTUNG !! Falsche CD, unbedingt wieder die passende CD einlegen"
  220.           SAY "> und mit Return bestätigen."
  221.  
  222.           PULL temp  /* auf Return warten */
  223.  
  224.           CALL get_toc()
  225.  
  226.        END /* do while */
  227.  
  228.     END /* if restore */
  229.  
  230.     ELSE DO
  231.  
  232.       restore = "N" /* restore und anz_save auf definierten Wert setzen sonst gibts evt. Probleme */
  233.       anz_save = 0
  234.  
  235.     END
  236.  
  237.   END /* if rip.. */
  238.  
  239.   ELSE DO /* Notbremse bei Fehler */
  240.  
  241.     SAY "> Daten der letzen Bearbeitung konnten nicht eingelesen werden."
  242.     SAY "> Wahrscheinlich ist die Datei "list_in" defekt. :-("
  243.     SAY "> Hilft nichts, alles nochmal neu eingeben ;-)"
  244.  
  245.     restore = "N"
  246.     anz_save = 0
  247.     mp3 = "N"
  248.  
  249.   END /* else - if rip.. */
  250.  
  251. END /* if exists */
  252.  
  253.  
  254. /** 1b. Inhaltsverzeichnis einlesen und auswerten **/
  255.  
  256. IF (restore ~== "J") THEN DO  /* aber nicht wenn eine Sitzung fortgeführt wird */
  257.  
  258.   CALL get_toc()
  259.  
  260.   IF (anz_titel > 0) THEN DO
  261.  
  262.     SAY
  263.     SAY "> CD Inhalt eingelesen, insgesamt "anz_titel" Titel:"
  264.  
  265.     IF cdid_mode == 1 THEN DO
  266.  
  267.       li = 10  /* mindestlaenge interpret (wegen text) */
  268.       ln = 6   /* mindestlaenge titel */
  269.  
  270.       DO a = 1 to anz_titel
  271.  
  272.         IF LENGTH(cd.a.ip) > li THEN li = LENGTH(cd.a.ip)+1      /* min.laenge interpret anpassen wenn länger */
  273.         IF LENGTH(cd.a.name) > ln THEN ln = LENGTH(cd.a.name)+1  /* min.laenge titel anpassen wenn länger */
  274.  
  275.       END /* do a */
  276.  
  277.       b = " Titel | Interpret"INSERT('','',0,li-9,' ')"| Titel"INSERT('','',0,ln-5,' ')"| Länge "  /* Länge des Headers */
  278.  
  279.       IF list_win == 1 THEN DO /* Inhalt in eigenem Fenster darstellen ? ... */
  280.         c = (LENGTH(b)+4)*lw_fw
  281.         d = (anz_titel+8)*lw_fh
  282.         OPEN(lw,'CON:'lw_xs'/'lw_ys'/'c'/'d'/CD-List')
  283.       END
  284.  
  285.       ELSE                     /* ... nöö */
  286.         OPEN(lw,"*")
  287.  
  288.       WRITELN(lw,"CD-Interpret: "cd.0.ip)
  289.       WRITELN(lw,"CD-Titel    : "cd.0.name)
  290.       WRITELN(lw,'')
  291.  
  292.       WRITELN(lw,b)
  293.  
  294.       WRITELN(lw,INSERT('','',1,LENGTH(b)+2,'-'))
  295.  
  296.       DO a = 1 to anz_titel /* titel ausgeben */
  297.  
  298.         WRITELN(lw, INSERT('','',0,4-(a > 9),' ')||cd.a.nr"  - "cd.a.ip||INSERT('','',0,li-LENGTH(cd.a.ip),' ')"- "cd.a.name||INSERT('','',0,ln-LENGTH(cd.a.name),' ')"- "cd.a.zeit)
  299.  
  300.       END /* do a */
  301.  
  302.       WRITELN(lw, INSERT('','',0,LENGTH(b)+3,'-'))
  303.       WRITELN(lw, INSERT('','',0,li+ln+5,' ')"Gesamt: "cd.a.zeit)
  304.  
  305.     END /* if cdid_mode */
  306.  
  307.     ELSE DO  /* keine cdid vorhanden, daher auch keine titelnamen */
  308.  
  309.       IF list_win == 1 THEN DO
  310.         c= 21*lw_fw
  311.         d= (anz_titel+6)*lw_fh
  312.         OPEN(lw,'CON:'lw_xs'/'lw_ys'/'c'/'d'/CD-List')
  313.       END
  314.  
  315.       ELSE
  316.         OPEN(lw,"*")
  317.  
  318.       WRITELN(lw,'')
  319.       WRITELN(lw," Titel | Länge")
  320.       WRITELN(lw,"--------------------")
  321.  
  322.       DO a = 1 to anz_titel
  323.  
  324.         WRITELN(lw, INSERT('','',0,5-(a > 9),' ')||cd.a.nr" - "cd.a.zeit)
  325.  
  326.       END /* Do */
  327.  
  328.       WRITELN(lw,"--------------------")
  329.       WRITELN(lw," Gesamt: "cd.a.zeit)
  330.  
  331.     END
  332.  
  333.   /** 2. Titel zum abspeichern auswaehlen **/
  334.  
  335.     akt_t = 0
  336.     rip.0.cdt = "dummy"
  337.     gr = 0
  338.  
  339.     /* titel zum Abspeichern holen bis keine Eingabe mehr */
  340.     SAY
  341.     SAY "Erlaubte Eingaben: 1-"anz_titel", b = letzten Titel löschen, nur Return = ende"
  342.     SAY
  343.  
  344.     DO UNTIL rip.akt_t.cdt==""
  345.  
  346.       akt_t = akt_t +1
  347.  
  348.       WRITECH(stdout,"> Bitte "akt_t". gewünschten Titel eingeben: ")
  349.       PULL rip.akt_t.cdt
  350.  
  351.       /* evt. eingegebener Abzug vom Leadout auswerten */
  352.       IF LEFT(rip.akt_t.cdt,1) == "-" THEN DO
  353.  
  354.          /* leadout abzug vom Titel trennen */
  355.          PARSE VALUE rip.akt_t.cdt WITH cut' 'temp
  356.  
  357.          IF temp == "" THEN  /* Titel vergessen oder falsch eingegeben */
  358.  
  359.             rip.akt_t.cdt = "X"
  360.  
  361.          ELSE DO
  362.  
  363.            rip.akt_t.cdt = temp  /* titel wieder eintragen */
  364.  
  365.            cut = TRANSLATE(cut,'.',',') /* komma durch punkt ersetzten wenn vorhanden */
  366.  
  367.            /* und neuen zusätzlichen abzug ausrechnen. Scheint insgesamt etwas kompliziert, aber so kann ich mehr oder
  368.               weniger als den standardabzug abschneiden */
  369.            rip.akt_t.cut_lo = ((cut * -75) % 1) - skip_lo
  370.  
  371.            /* abzug + standardabzug dürfen natürlich nicht länger als der titel sein */
  372.            IF (rip.akt_t.cut_lo + skip_lo) > cd.temp.laenge THEN DO
  373.  
  374.              SAY "> Scherzkeks, das machen wir nochmal..."
  375.  
  376.              rip.akt_t.cut_lo = 0
  377.              rip.akt_t.cdt    = "X"
  378.  
  379.            END /* if */
  380.  
  381.            IF debug == 1 THEN
  382.              SAY "Abzug: "cut" Titel: "temp" zus.Abzug: "rip.akt_t.cut_lo" Standardabz.: "skip_lo
  383.  
  384.         END /* if temp */
  385.  
  386.       END /* if left */
  387.  
  388.       ELSE
  389.         rip.akt_t.cut_lo = 0 /* ohne Eingabe standardabzug nicht ändern */
  390.  
  391.       /* Eingabe erfolgt oder -> eingabeende ? */
  392.       IF rip.akt_t.cdt ~== "" THEN DO
  393.  
  394.         /* erstmal schauen ob wir den Titel nicht schon hatten. Geht auch eleganter aber es sind */
  395.         /* ja höchstens 20 Titel                                                                 */
  396.  
  397.         DO a = 1 TO (akt_t -1)
  398.  
  399.            IF rip.akt_t.cdt == rip.a.cdt THEN DO
  400.  
  401.              SAY ">>>> Also den Titel hatten wir schon mal."
  402.              SAY
  403.  
  404.              rip.akt_t.cdt = "X" /* X ist eine ungültige Angabe und wird im Select entsprechend behandelt */
  405.  
  406.            END /* if rip.. */
  407.  
  408.         END /* do a */
  409.  
  410.         SELECT
  411.  
  412.           /* Titel im erlaubten Bereich ? */
  413.           WHEN (rip.akt_t.cdt >= 1) & (rip.akt_t.cdt <= anz_titel) THEN DO
  414.  
  415.             a = rip.akt_t.cdt
  416.  
  417.             IF cdid_mode == 1 THEN                        /* zugehörenden mp3-namen generieren */
  418.  
  419.               IF LENGTH(cd.a.cdn) > max_name_len-4 THEN   /* genug Platz für extension ? */
  420.                 rip.akt_t.mpn = LEFT(cd.a.cdn, max_name_len-4)||".mp3"
  421.               ELSE
  422.                 rip.akt_t.mpn = cd.a.cdn||".mp3"
  423.  
  424.             ELSE /* if cdid_mode */
  425.               rip.akt_t.mpn = "Titel"rip.akt_t.cdt".mp3"  /* zugehörenden default mp3-namen generieren */
  426.  
  427.             /* Vorabinfo wieviel Platz ca. benötigt wird */
  428.             gr = gr + (((cd.a.laenge - rip.akt_t.cut_lo) * bpb) % 1048576)
  429.  
  430.             SAY "> benötigter Speicherplatz bis jetzt ca. "gr" MB."
  431.             SAY
  432.  
  433.           END /* when */
  434.  
  435.           /* letzte Eingabe löschen */
  436.           WHEN (rip.akt_t.cdt == "B") & (akt_t > 1) THEN DO
  437.  
  438.             akt_t = akt_t -2  /* laufvariable zurücksetzen */
  439.  
  440.             /* Speicheranzeige korrigieren und neu ausgeben, gibt natürlich Rundungsfehler ist aber eh' nur ca. */
  441.             a = rip.akt_t.cdt
  442.             gr = gr - (((cd.a.laenge - rip.akt_t.cut_lo) * bpb) % 1048576) + 1
  443.  
  444.             SAY "> benötigter Speicherplatz neu jetzt ca. "gr" MB."
  445.             SAY
  446.  
  447.           END /* when */
  448.  
  449.           /* falsche Eingabe */
  450.           OTHERWISE
  451.  
  452.             akt_t = akt_t -1  /* laufvariable wieder zurücksetzen */
  453.  
  454.         END /* Select */
  455.  
  456.       END /* if rip.. */
  457.  
  458.     END /* Do until */
  459.  
  460.     CLOSE(lw)  /* CD Window wieder schliessen */
  461.  
  462.     anz_save = akt_t -1
  463.  
  464.     /* Titel ausgewählt? */
  465.     IF anz_save > 0 THEN DO
  466.  
  467.       /* ermitteln ob auch mp3 erzeugt werden soll */
  468.       SAY
  469.       WRITECH(stdout,"> Sollen die Songs auch gleich ins mp3-Format umgewandelt werden (j/N)? : ")
  470.  
  471.       PULL mp3
  472.  
  473.       IF mp3 == "J" THEN DO
  474.  
  475.         IF cdid_mode == 0 THEN DO
  476.  
  477.           /* filenamen für mp3-files ermitteln. Bei vorhandenen cdids wUrden die Namen automatisch generiert.
  478.              Prinzipiell können auch noch Pfadangaben vor dem Filenamen erfolgen solange die max. Länge von
  479.              26 Zeichen nicht überschritten wird (dir/dir/name).
  480.              Einfacher ist es aber den globalen Pfad richtig einzustellen.
  481.  
  482.              Überprüfung der Gültigkeit:
  483.              FFS max 30 Zeichen (26 + .mp3 = 30)
  484.              keine ~ % # ? < > | ( ) [ ] " Zeichen
  485.           */
  486.  
  487.           a = 0
  488.           b = ""
  489.  
  490.           /* Die Eingabe der Dateinnamen kann nicht mit Pull erfolgen da dabei alles in Grossbuchstaben
  491.              umgewandelt wird. Der einzige mir bekannte Weg dies ohne CON: zu umgehen, ist das Einlesen mit Parse
  492.              aus STDERR. Kollidiert allerdings mit evt. offenen Debug-Fenstern
  493.           */
  494.           CALL OPEN(STDERR, "*", 'R')
  495.  
  496.           DO UNTIL a == anz_save
  497.  
  498.             a = a +1
  499.  
  500.             SAY
  501.             SAY "> Dateiname für mp3-file von Titel "rip.a.cdt" eingeben (ohne extension, default = "rip.a.mpn") : "
  502.  
  503.             PARSE EXTERNAL b
  504.  
  505.             /* wenn ein Name eingegeben wurde diesen uebernehmen ansonsten den defaultnamen verwenden */
  506.             IF b ~== "" THEN DO
  507.  
  508.               temp = b
  509.  
  510.               b = create_name(b, max_name_len - LENGTH(mp_ext))
  511.  
  512.               IF b ~== temp THEN DO
  513.                 SAY
  514.                 SAY "> Dateiname angepasst:" b
  515.  
  516.               END /* if b/temp */
  517.  
  518.               rip.a.mpn = b||mp_ext
  519.  
  520.             END /* if b/"" */
  521.  
  522.           END /* Do until */
  523.  
  524.           CLOSE(STDERR) /* wir sind ein ordentliches Völkchen ;-) */
  525.  
  526.         END /* if cdid_mode */
  527.  
  528.       END /* if mp3 */
  529.  
  530.     END /* if anz_save */
  531.  
  532.   END /* if anz_titel */
  533.  
  534. END /* if restore */
  535.  
  536. /** jetzt kommt sie eigentliche Arbeit, natürlich nur wenn auch Titel ausgewählt wurden **/
  537.  
  538. IF anz_save > 0 THEN DO
  539.  
  540.   /* bei restore wird gleich begonnen, ansonsten erfolgt abfrage ob die angaben nur gespeichert werden sollen.
  541.      Damit kann während eine CD bearbeitet wird bereits die nächste vorbereiten. Skript dann mit Dateinamen starten. */
  542.  
  543.   IF restore ~== "J" THEN DO
  544.     WRITECH(stdout,"> Gleich mit der Bearbeitung beginnen oder Angaben nur speichern (g/S)? ")
  545.  
  546.     PULL doit
  547.  
  548.   END /* if restore */
  549.  
  550.   ELSE
  551.     doit = "G"
  552.  
  553.   IF doit == "G" THEN DO
  554.  
  555.     /* erstmal bisherige Angaben speichern. Abspeichern erfolgt erst jetzt da es bei späterer bearbeitung nicht
  556.        nötig ist die Daten unter dem Backupnamen zu speichern, evt. würde das auch mit einer gerade laufenden
  557.        Sitzung kollidieren. Tut es zwar auch wenn eine Instanz gerade mp3 erzeugt und die neue nur cd-files, aber
  558.        einen Tod muss man sterben. Wenn ich erst nach dem Erzeugen der CD-files abspeichere ist das Risiko zu gross
  559.        dass die Daten durch Absturz verlorengehen. (die ca. 50 MB einer Datei quälen sich bei mir in ca. 40s.
  560.        auf die Platte.)
  561.     */
  562.     CALL save_datei(titellist,1,anz_save) /* Titelliste für restore abspeichern */
  563.  
  564.     a=1
  565.  
  566.     SAY
  567.  
  568.     /* alle Titel erstmal auf HD speichern. Keine Abfrage auf ausreichend freien Speicherplatz. Wüsste nicht wie */
  569.     DO WHILE a <= anz_save
  570.  
  571.       akt_t = rip.a.cdt
  572.  
  573.       cd.akt_t.laenge = cd.akt_t.laenge - rip.a.cut_lo /* titellaenge um evt. eingegebenen abzug korrigieren */
  574.  
  575.       gr = (cd.akt_t.laenge * bpb) % 1048576   /* nur ca-Wert */
  576.  
  577.       SAY "> Speichere Lied Nr." akt_t" als "titelpfad||cd.akt_t.cdn", Grösse ca. "gr" MB"
  578.  
  579.       /* CD-Titel einlesen und abspeichern */
  580.       IF debug == 1 THEN
  581.         SAY "cdda PLAN="plan" MUTE FILE="'"'titelpfad||cd.akt_t.cdn'"'" START="cd.akt_t.start" LENGTH="cd.akt_t.laenge
  582.       
  583.       ELSE
  584.         ADDRESS COMMAND "cdda PLAN="plan" MUTE FILE="'"'titelpfad||cd.akt_t.cdn'"'" START="cd.akt_t.start" LENGTH="cd.akt_t.laenge
  585.  
  586.       a = a +1
  587.  
  588.     END /* Do while */
  589.  
  590.     SAY
  591.     SAY "> CD wird nicht mehr benötigt"
  592.  
  593.     /* ggf. mp3-files erzeugen */
  594.     IF mp3 == "J" THEN DO
  595.  
  596.       SAY
  597.       SAY "> erzeuge jetzt die entsprechenden mp3-files ->"
  598.  
  599.       a = 1
  600.  
  601.       DO WHILE a <= anz_save
  602.  
  603.         b = rip.a.cdt
  604.  
  605.         SAY
  606.         SAY "> Titel Nr." b "unter "mp3pfad||rip.a.mpn
  607.         SAY
  608.  
  609.         /* mp3 erzeugen */
  610.         IF debug == 1 THEN DO
  611.           SAY "lame "lameopt '"'titelpfad||cd.b.cdn'"' '"'mp3pfad||rip.a.mpn'"'
  612.           SAY "pegase "pegaseopt "FROM "'"'titelpfad||cd.b.cdn'"'" TO "'"'mp3pfad||rip.a.mpn'"'
  613.         END
  614.  
  615.         ELSE
  616.  
  617.           SELECT
  618.  
  619.             WHEN encoder == "lame" THEN DO /* Lame ... */
  620.  
  621.               IF lame_ppc == "1" THEN DO        /* (PPC-Lame setzt den Stack nicht selbst, daher bauen wir uns */
  622.                 OPEN(ns,"T:ns",W)               /* eine Batchdatei, etwas tricky aber es funktioniert) */
  623.                 WRITELN(ns, "stack "ppc_stack)
  624.                 WRITELN(ns, "lame "lameopt '"'titelpfad||cd.b.cdn'"' '"'mp3pfad||rip.a.mpn'"')
  625.                 CLOSE(ns)
  626.  
  627.                 ADDRESS COMMAND "Execute T:ns"     /* Batch starten */
  628.                 ADDRESS COMMAND "Delete >NIL: T:ns" /* und schnell löschen, bevor es jemand sieht */
  629.  
  630.               END
  631.  
  632.               ELSE /* 68k-Lame kümmert sich selbst um den Stack, danke */
  633.                 ADDRESS COMMAND "lame "lameopt '"'titelpfad||cd.b.cdn'"' '"'mp3pfad||rip.a.mpn'"'
  634.  
  635.             END
  636.  
  637.             WHEN encoder == "pegase" THEN /* ... oder Pegase. Das ist hier die Frage */
  638.               ADDRESS COMMAND "pegase "pegaseopt "FROM "'"'titelpfad||cd.b.cdn'"'" TO "'"'mp3pfad||rip.a.mpn'"'
  639.  
  640.             OTHERWISE
  641.               SAY "Oops, unknown encoder, please check the parameters"
  642.  
  643.           END /* select */
  644.  
  645.         CALL save_datei(titellist,a+1,anz_save) /* fertige files aus abgespeicherter Titelliste entfernen */
  646.  
  647.         /* CD-file löschen */
  648.         IF debug == 1 THEN
  649.           SAY "Delete" '"'titelpfad||cd.b.cdn'"'
  650.  
  651.         IF (debug == 0) & (del_titel == 1) THEN
  652.           ADDRESS COMMAND "Delete >NIL: "'"'titelpfad||cd.b.cdn'"'
  653.  
  654.         a = a +1
  655.  
  656.       END /* Do while */
  657.  
  658.     END /* If mp3 */
  659.  
  660.     ELSE /* wenn nur Audio-Dateien erzeugt wurden wird titelliste nicht mehr gebraucht */
  661.       ADDRESS COMMAND "Delete >NIL: "'"'titelpfad||titellist'"'
  662.  
  663.   END /* if doit */
  664.  
  665.   ELSE DO  /* if doit - Daten für spätere Bearbeitung speichern */
  666.  
  667.     /* Dateiname mit CD-Titel oder Defaultname vorbelegen */
  668.     IF cdid_mode == 1 THEN
  669.       listname = cd.0.name
  670.     ELSE
  671.       listname = cdsave
  672.  
  673.     listname = create_name(listname, max_name_len) /* an Dos anpassen */
  674.  
  675.     /* und fragen ob's dem Herrn Anwender gefällt */
  676.     SAY
  677.     SAY "> Bitte Dateinamen zum Abspeichern der Titelliste eingeben."
  678.     SAY "> (default="listname"):"
  679.  
  680.     PULL a
  681.  
  682.     IF a ~== "" THEN DO /* check ob neuer name eingegeben wurde, wenn ja diesen verwenden */
  683.       listname = a
  684.       listname = create_name(listname, max_name_len) /* neuen Namen an Dos anpassen */
  685.     END
  686.  
  687.     SAY
  688.     SAY "> Danke, Titelliste wird unter <"listname"> gespeichert."
  689.     SAY "> Sobald die Liste bearbeitet werden soll, cdmp.rx mit"
  690.     SAY "> diesem Namen als Parameter starten."
  691.     SAY "> Also: cdmp.rx "listname
  692.  
  693.     CALL save_datei(listname,1,anz_save)
  694.  
  695.   END /* Else - if doit */
  696.  
  697. END /* If anz_save */
  698.  
  699. SAY
  700. SAY "> Ok, das war's und tschüssss........"
  701. SAY
  702.  
  703. ende:
  704.  
  705. ADDRESS COMMAND "WAIT 5"
  706.  
  707. EXIT
  708.  
  709.  
  710.  
  711. /**********************/
  712. /**** Sub-routinen ****/
  713. /**********************/
  714.  
  715. /****
  716.  
  717.   save_datei - speichert unter dem angebenen Dateinamen die Variablen cdid, mp3  und den Inhalt der rip-Variablen
  718.                von 'start' bis 'ende' im zugewiesenen Datenverzeichnis.
  719.                Keine Fehlerabfrage - zuviel Aufwand für relativ unwichtige Daten
  720.  
  721.   template: save_datei(datei,start,ende)
  722.  
  723. ****/
  724.  
  725. save_datei:
  726.  
  727.   PARSE ARG sdatei, sstart, sende
  728.  
  729.   IF sstart > sende THEN ADDRESS COMMAND "Delete >NIL: "titelpfad||sdatei
  730.  
  731.   ELSE DO
  732.  
  733.     OPEN(datei_out,titelpfad||sdatei,W)
  734.  
  735.     WRITELN(datei_out, cdid)
  736.     WRITELN(datei_out, mp3)
  737.  
  738.     DO sa = sstart TO sende
  739.  
  740.       IF debug == 1 THEN SAY "Speichere "rip.sa.cdt", "rip.sa.mpn", "rip.sa.cut_lo
  741.  
  742.       WRITELN(datei_out, rip.sa.cdt)
  743.       WRITELN(datei_out, rip.sa.mpn)
  744.       WRITELN(datei_out, rip.sa.cut_lo)
  745.  
  746.     END /* do sa */
  747.  
  748.     CLOSE(datei_out)
  749.  
  750.   END /* else */
  751.  
  752. RETURN
  753.  
  754. /* ---------------------------- */
  755.  
  756.  
  757. /****
  758.  
  759.   create_id  - erzeugt einen CDID String.
  760.  
  761.   globalen Variablen: anz_titel und cd.
  762.   lokale VAriablen  : sa
  763.  
  764. ****/
  765.  
  766. create_id:
  767.  
  768.   sa = "ID"
  769.  
  770.   IF anz_titel > 9 THEN
  771.  
  772.     sa = sa||anz_titel
  773.  
  774.   ELSE
  775.     sa = sa||'0'||anz_titel
  776.  
  777.   IF anz_titel == 2 THEN  /* kann man Singles mit 'nem CD-Rom lesen ? na, sicher ist sicher */
  778.     sa = sa||D2X(cd.anz_titel.ende+1,6)||D2X(cd.anz_titel.ende+1,6)
  779.  
  780.   ELSE
  781.     sa = sa||D2X(cd.3.start,6)||D2X(cd.anz_titel.ende+1,6)
  782.  
  783.   IF debug == 1 THEN SAY sa
  784.  
  785. RETURN sa
  786.  
  787. /* ---------------------------- */
  788.  
  789.  
  790. /****
  791.  
  792.   get_toc  - liest und überträgt das Inhaltsverzeichnis der CD.
  793.  
  794.   globale Variablen: cd., akt_titel, cdlist, anz_titel, cdid, cdid_mode
  795.   lokale Variablen : datei_in, zeile, akt_t, cdnr, dummy
  796.  
  797. ****/
  798.  
  799. get_toc:
  800.  
  801.   ADDRESS COMMAND "cdda plan="plan" list >"cdlist
  802.  
  803.   IF EXISTS(cdlist) THEN DO
  804.  
  805.     OPEN(datei_in,cdlist,R)
  806.  
  807.     /* 1.Zeile -> wegschmeissen) */
  808.     zeile = READLN(datei_in)
  809.  
  810.     akt_t = 0
  811.     cdnr = ""
  812.  
  813.     /* titel einlesen bis total oder eof erreicht */
  814.     DO WHILE ( (cdnr ~== "TOT:") & ~eof(datei_in) )
  815.  
  816.       /* 2.+...Zeile -> einlesen und auswerten)  */
  817.       zeile = READLN(datei_in)
  818.  
  819.       /* laufvariable fuer stamm */
  820.       akt_t = akt_t +1
  821.  
  822.       cd.akt_t.nr = akt_t
  823.       cd.akt_t.cdn = "Titel"akt_t
  824.  
  825.       /* in teilstrings zerlegen, unwichtiges mit dummy wegwerfen */
  826.       PARSE VALUE zeile WITH cdnr cd.akt_t.start dummy cd.akt_t.ende dummy cd.akt_t.laenge cd.akt_t.zeit dummy
  827.  
  828.       cd.akt_t.laenge = cd.akt_t.laenge - skip_lo /* Leadout kürzen */
  829.  
  830.       cd.akt_t.zeit = SUBSTR(cd.akt_t.zeit, 2, 8)
  831.  
  832.       IF debug == 1
  833.         THEN say cd.akt_t.nr": " cdnr cd.akt_t.start cd.akt_t.ende cd.akt_t.laenge cd.akt_t.zeit dummy
  834.  
  835.     END /* do while */
  836.  
  837.     CLOSE(datei_in)
  838.  
  839.     ADDRESS COMMAND "Delete >NIL: "'"'cdlist'"'  /* liste wird nicht mehr gebraucht */
  840.  
  841.   END /* if exists */
  842.  
  843.   anz_titel = akt_t -1
  844.  
  845.   SELECT
  846.  
  847.     WHEN anz_titel < 1 THEN DO
  848.       SAY
  849.       SAY "> Hmmm, keine CD im Laufwerk oder Device/Unit falsch oder belegt!"
  850.     END
  851.  
  852.     WHEN anz_titel == 1 THEN DO  /* ich geh' mal davon aus das es keine Audio-Cds mit einem Titel gibt */
  853.       SAY
  854.       SAY "> Hmmm, scheint sich um eine Daten-CD zu handeln"
  855.       anz_titel = -1
  856.     END
  857.  
  858.     WHEN anz_titel > 1 THEN DO
  859.       cdid = create_id()
  860.       IF cdid_mode == 1 THEN
  861.         CALL read_cdid()
  862.     END
  863.   END /* select */
  864.  
  865. RETURN
  866.  
  867. /* ---------------------------- */
  868.  
  869.  
  870. /****
  871.  
  872.   get_cdname  - liest vorhandene cdid daten ein und wertet sie aus
  873.  
  874.   globalen Variablen: anz_titel, cdid_dir, cdid, max_nam_len und cd.
  875.   lokale variablen  : datei_in, akt_t, zeile, sa,
  876.  
  877. ****/
  878.  
  879. read_cdid:
  880.  
  881.   IF EXISTS(cdid_dir||cdid) THEN DO
  882.  
  883.     OPEN(datei_in,cdid_dir||cdid,R)
  884.  
  885.     akt_t = 0
  886.  
  887.     /* cd.0. enthält die globalen CD Daten */
  888.     cd.0.ip   = READLN(datei_in)  /* 1.Zeile -> Interpret der CD */
  889.     cd.0.name = READLN(datei_in)  /* 2.Zeile -> CD-Name          */
  890.  
  891.     /* titel einlesen bis eof erreicht */
  892.     DO WHILE (~eof(datei_in))
  893.  
  894.       akt_t = akt_t +1
  895.  
  896.       zeile = STRIP(READLN(datei_in)) /* zeile einlesen und führende und nachgestellte Leerzeichen entfernen */
  897.  
  898.       sa = POS('B7'x,zeile)           /* nach · suchen - trennt interpret und titel bei Samplern  */
  899.  
  900.       IF sa > 0 THEN DO
  901.  
  902.          cd.akt_t.ip   = STRIP(LEFT(zeile,sa-1))    /* links davon ist der Interpret */
  903.  
  904.          cd.akt_t.name = STRIP(SUBSTR(zeile,sa+1))  /* rechts der Titel */
  905.  
  906.       END
  907.       ELSE DO                        /* kein Sampler, Interpret ist für alle Titel derselbe */
  908.  
  909.          cd.akt_t.ip = cd.0.ip
  910.          cd.akt_t.name = zeile
  911.  
  912.       END
  913.  
  914.       cd.akt_t.cdn = create_name(cd.akt_t.name, max_name_len) /* entspr. Dateinamen generieren */
  915.  
  916.       IF debug == 1
  917.         THEN say cd.akt_t.nr": " zeile  sa  cd.akt_t.ip  cd.akt_t.name  cd.akt_t.cdn
  918.  
  919.     END /* do while */
  920.  
  921.     CLOSE(datei_in)
  922.  
  923.   END
  924.  
  925.   ELSE
  926.     cdid_mode = 0
  927.  
  928. RETURN
  929.  
  930. /* ---------------------------- */
  931.  
  932.  
  933.  
  934. /****
  935.  
  936.   create_name  - erzeugt aus einem übergebenen String und der max. Länge einen korrekten
  937.                  Dos-namen.
  938.  
  939.   globalen Variablen: dirty_char, repl_spc.
  940.   lokale variablen  : s_name, s_len
  941.  
  942. ****/
  943.  
  944. create_name:
  945.  
  946.   PARSE ARG s_name, s_len
  947.  
  948.   IF LENGTH(s_name) > s_len THEN               /* Dateinamenlänge prüfen und korrigieren */
  949.     s_name = LEFT(s_name,s_len)
  950.  
  951.   s_name = TRANSLATE(s_name,'',dirty_char,'_') /* Zeichen die mit Dos kollidieren durch Unterstrich ersetzen */
  952.  
  953.   IF (repl_spc == 1) THEN
  954.     s_name = TRANSLATE(s_name,'_',' ')    /* eingegebene Leerzeichen durch Unterstrich ersetzten falls erwünscht */
  955.  
  956. RETURN s_name
  957.  
  958. /* ---------------------------- */
  959.  
  960.  
  961.  
  962. /** CTRL-C Behandlung **/
  963.  
  964. break_c:
  965. failure:
  966.  
  967.   SAY ">>> Bearbeitung abgebrochen"
  968.  
  969.   SIGNAL ende
  970.  
  971. /* ---------------------------- */
  972.  
  973.